/* basic_pen.hh
* This file is part of ncursesxx library
* Copyright (c) 2003,2004 by Stanislav Ievlev
*
* This file is covered by the GNU Library General Public License,
* which should be included with libncursesxx as the file COPYING.
*/
#ifndef NCURSESXX_BASIC_PEN_HH__
#define NCURSESXX_BASIC_PEN_HH__

#include <string>

#include <curses.h>

#include <ncurses/window.hh>
#include <ncurses/pad.hh>
#include <ncurses/color.hh>
#include <ncurses/assert.hh>

namespace ncurses
{
	/**
	 * character traits for ncurses string works
	 */
	template <typename CharT> struct char_traits;
	template <typename CharT> struct acs;

	template <typename charT, typename Traits = char_traits<charT> > class basic_pen;

	/**
	 * pen to draw something inside window, 
	 * this is a general template both for widechar and non-widechar curses
	 */
	template <typename charT, typename Traits>
	class basic_pen
	{
		typedef std::char_traits<charT>	std_traits;
		typedef	std::basic_string<charT> string_type;
		typedef typename Traits::char_type	char_type;
	public:
		typedef acs<charT>	acs_charT; //pseudographic VT100 symbols
		//non-traits specific methods
		explicit
		basic_pen(window& win): win_(win.win()) {}

		explicit
		basic_pen(pad& pad): win_(pad.win()) {}

		void move(unsigned int x, unsigned int y) /**< move pen to the new position */
		{
			::wmove(win_, y, x);
		}
		void commit()
		{
		    NCURSES_ASSERT(::wnoutrefresh(win_));
		}
		unsigned int x() const /**< pen's position,first coordinate */
		{
			int x, y;
			getyx(win_, y, x);
			return x;
		}
		unsigned int y() const /**< pen's position,second coordinate */
		{
			int x, y;
			getyx(win_, y, x);
			return y;
		}
		void clear()
		{
			::werase(win_);
		}
		void fill(const color& col)
		{
			::wbkgd(win_, COLOR_PAIR(col.num()));
			//FIXME: move to traits and use wbkgrnd for widechar version
			/*
			    NCURSES_EXPORT(int)
			    wbkgd(WINDOW *win, chtype ch)
			    {
				NCURSES_CH_T wch;
				SetChar2(wch, ch);
				return wbkgrnd(win, CHREF(wch));
			    }
			*/
		}
		void set_color(const color& c)
		{ //what should I use here: wattrset or wattr_set
			wattr_set(win_, c.attr(), c.num(), 0);
		}

		//traits specific functions
		void frame() { Traits::frame(win_); }
		void write(const string_type& str) { Traits::write(win_, str.c_str(), str.length()); }
		void write(const char_type ch) { Traits::write(win_, ch); }
		void h_line(int n, const char_type ch = acs_charT::h_line()) { Traits::h_line(win_, ch, n); }
		void v_line(int n, const char_type ch = acs_charT::v_line()) { Traits::v_line(win_, ch, n); }
	private:
		WINDOW *win_; /**< window object we draw it*/
	};
}
#endif
